#include "displaycanvascalculator.h"
#include <QDebug>
#include <QScreen>
#include <QGuiApplication>
#include <cmath>
// === DisplayCanvasCalculator实现 ===
// Martin Fowler重构：Extract Method + Replace Magic Number
DisplayCanvasCalculator::DisplayInfo DisplayCanvasCalculator::getCurrentDisplayInfo(QScreen* screen)
{
    // 如果未指定屏幕，使用主屏幕
    if (!screen) {
        screen = QGuiApplication::primaryScreen();
    }
    if (!screen) {
        return {}; // 返回默认构造的DisplayInfo
    }
    DisplayInfo info;
    info.screen = screen;
    // 获取Qt报告的逻辑DPI
    info.logicalDpi = screen->logicalDotsPerInch();
    // 获取设备像素比（高DPI屏幕支持）
    info.devicePixelRatio = screen->devicePixelRatio();
    // 计算物理DPI
    info.physicalDpi = info.logicalDpi;
    // 获取屏幕几何信息
    info.screenSize = screen->size();
    info.physicalSizeMM = screen->physicalSize();
    // 如果物理尺寸有效，重新计算更准确的物理DPI
    if (info.physicalSizeMM.width() > 0 && info.physicalSizeMM.height() > 0) {
        double physicalWidthInches = info.physicalSizeMM.width() / MM_PER_INCH;
        double physicalHeightInches = info.physicalSizeMM.height() / MM_PER_INCH;
        double dpiX = info.screenSize.width() / physicalWidthInches;
        double dpiY = info.screenSize.height() / physicalHeightInches;
        // 使用平均值作为物理DPI
        info.physicalDpi = (dpiX + dpiY) / 2.0;
    }
    return info;
}
QSize DisplayCanvasCalculator::calculateA4PhysicalSize(const DisplayInfo& display)
{
    // Martin Fowler: Extract Method - 将A4尺寸计算提取为独立方法
    // 使用推荐的显示DPI进行计算
    double displayDpi = getRecommendedDisplayDpi(display);
    // 计算A4在屏幕上的实际像素大小
    int width = mmToPixels(A4_WIDTH_MM, displayDpi);
    int height = mmToPixels(A4_HEIGHT_MM, displayDpi);
    // 应用设备像素比（为高DPI屏幕调整）
    width = qRound(width * display.devicePixelRatio);
    height = qRound(height * display.devicePixelRatio);
    return QSize(width, height);
}
double DisplayCanvasCalculator::getRecommendedDisplayDpi(const DisplayInfo& display)
{
    // Martin Fowler: Replace Conditional with Polymorphism思想
    // 根据平台和屏幕特性选择最佳DPI
    double baseDpi = getPlatformBaseDpi();
    // 如果有可靠的物理DPI信息，优先使用
    if (display.physicalSizeMM.width() > 0 && display.physicalSizeMM.height() > 0) {
        // 使用物理DPI，但限制在合理范围内
        double physicalDpi = display.physicalDpi;
        // 限制DPI在合理范围内（72-200）
        if (physicalDpi >= 72.0 && physicalDpi <= 200.0) {
            return physicalDpi;
        }
    }
    // 对于高DPI屏幕，使用调整后的DPI
    if (display.isHighDpiScreen()) {
        return adjustForHighDpiScreen(display);
    }
    // 否则使用逻辑DPI或平台默认值
    return qMax(display.logicalDpi, baseDpi);
}
QSize DisplayCanvasCalculator::calculatePhysicalPixelSize(const QSizeF& sizeMM, const DisplayInfo& display)
{
    double displayDpi = getRecommendedDisplayDpi(display);
    int width = mmToPixels(sizeMM.width(), displayDpi);
    int height = mmToPixels(sizeMM.height(), displayDpi);
    // 应用设备像素比
    width = qRound(width * display.devicePixelRatio);
    height = qRound(height * display.devicePixelRatio);
    return QSize(width, height);
}
double DisplayCanvasCalculator::calculateDpiScaleFactor(double sourceDpi, double targetDpi)
{
    if (sourceDpi <= 0 || targetDpi <= 0) {
        return 1.0;
    }
    return targetDpi / sourceDpi;
}
QString DisplayCanvasCalculator::getDisplayDiagnostics(const DisplayInfo& display)
{
    QString diagnostics;
    QTextStream stream(&diagnostics);
    stream << "=== 显示器诊断信息 ===" << Qt::endl;
    stream << QString("屏幕名称: %1").arg(display.screen ? display.screen->name() : "未知") << Qt::endl;
    stream << QString("逻辑DPI: %1").arg(display.logicalDpi) << Qt::endl;
    stream << QString("物理DPI: %1").arg(display.physicalDpi) << Qt::endl;
    stream << QString("设备像素比: %1").arg(display.devicePixelRatio) << Qt::endl;
    stream << QString("屏幕尺寸: %1×%2像素").arg(display.screenSize.width()).arg(display.screenSize.height()) << Qt::endl;
    stream << QString("物理尺寸: %1×%2毫米").arg(display.physicalSizeMM.width()).arg(display.physicalSizeMM.height()) << Qt::endl;
    stream << QString("推荐显示DPI: %1").arg(getRecommendedDisplayDpi(display)) << Qt::endl;
    QSize a4Size = calculateA4PhysicalSize(display);
    stream << QString("A4物理像素: %1×%2").arg(a4Size.width()).arg(a4Size.height()) << Qt::endl;
    return diagnostics;
}
bool DisplayCanvasCalculator::validateDpiCalculation(const DisplayInfo& display)
{
    // 验证DPI计算的合理性
    double recommendedDpi = getRecommendedDisplayDpi(display);
    // DPI应该在合理范围内
    if (recommendedDpi < 50.0 || recommendedDpi > 300.0) {
        return false;
    }
    // A4尺寸应该在合理范围内
    QSize a4Size = calculateA4PhysicalSize(display);
    if (a4Size.width() < 100 || a4Size.height() < 100 ||
        a4Size.width() > 4000 || a4Size.height() > 4000) {
        return false;
    }
    return true;
}
// === 私有辅助方法实现 ===
double DisplayCanvasCalculator::getPlatformBaseDpi()
{
    // Martin Fowler: Replace Conditional with Polymorphism思想
    // 根据平台返回合适的基础DPI
#ifdef Q_OS_MACOS
    return MACOS_DISPLAY_DPI;
#elif defined(Q_OS_WINDOWS)
    return RECOMMENDED_DISPLAY_DPI;
#else
    return RECOMMENDED_DISPLAY_DPI; // Linux等其他平台
#endif
}
double DisplayCanvasCalculator::adjustForHighDpiScreen(const DisplayInfo& display)
{
    // 对于高DPI屏幕，需要特殊处理
    // 避免过度缩放导致的显示问题
    double adjustedDpi = display.logicalDpi;
    // 对于非常高的设备像素比，适当降低DPI以保持合理的显示大小
    if (display.devicePixelRatio >= 2.0) {
        adjustedDpi = display.logicalDpi / qSqrt(display.devicePixelRatio);
    }
    // 确保调整后的DPI在合理范围内
    return qBound(72.0, adjustedDpi, 200.0);
}
int DisplayCanvasCalculator::mmToPixels(double mm, double dpi)
{
    // Martin Fowler: Extract Method - 精确的毫米到像素转换
    return qRound(mm / MM_PER_INCH * dpi);
}
double DisplayCanvasCalculator::pixelsToMM(int pixels, double dpi)
{
    // 像素到毫米的反向转换
    return (pixels * MM_PER_INCH) / dpi;
}